
 #######################                     
##    COPYRIGHT(C):    ##
# TOMMY ANDRE BERTELSEN #
#       480266          #
#  NEURAL NETWORK AGENT #
## 'competition agent' ##
 #######################


# Modules/Libraries:
import pybrain
import pickle
import random
import urllib
import math
import time

# External Modules/Libraries:
from pybrain.tools.shortcuts import buildNetwork
from pybrain.structure import TanhLayer
from bs4 import BeautifulSoup

# Bool to keep the program running:
isRunning = True
maxDays = 26

#Clear logfile:
f = open("logFile.txt", "w")
f.write("")
f.close()

lastDate = "NaN"


# Loop for 26 days:
while(isRunning):
	#Set some variables:
	# Scaling:
	s = 1000.0
	
	log = []

	# Read init file:
	# Open file with data:
	f = open('init.txt')
	initLines = f.readlines()
	f.close()
	
	# Init values:
	buyPercent = 0.0;
	sellPerCent = 0.0;
	real = 0.0
	estimated = 0.0;
	yesterday = 0.0;
	initDay = int(initLines[0])
	day = initDay
	initAssetNOK = float(initLines[1]) 
	initAssetMWH = float(initLines[2])
	currentAssetNOK = initAssetNOK
	currentAssetMWH = initAssetMWH

	#log initial values:
	log.append("Day:                       " + str(day) + "\n")
	log.append("Initial Asset (NOK):       " + str(currentAssetNOK) + "\n")
	log.append("Initial Asset (MWH):       " + str(currentAssetMWH) + "\n")
	

	# Parse the data and return date and time:
	def webParserDate():
		# Open URL and use BS to get the wanted data:
		url = urllib.urlopen('http://demo.cognit.no/nordpool/')
		soup = BeautifulSoup(url)

		# Find correct span:
		span = soup.find("span", {"id":"MainContent_dummyPlaceholder"})      

		# Set span data to string:
		tmptxt = span.get_text()
		# Replace commas (,) with punctuations (.):
		tmptxt = tmptxt.replace(',','.')
		# Strip whitespaces:
		tmptxt = tmptxt.strip()
	
		# Get todays price (at the end):
		dateToday = tmptxt[-41:-23]
		# Return this price:
		return dateToday
		
	if(webParserDate() != lastDate):
		# Print day:
		print 'Day ' + repr(day)
		lastDate = webParserDate()
		def webParser():
			# Open URL and use BS to get the wanted data:
			url = urllib.urlopen('http://demo.cognit.no/nordpool/')
			soup = BeautifulSoup(url)

			# Find correct span:
			span = soup.find("span", {"id":"MainContent_dummyPlaceholder"})      

			# Set span data to string:
			tmptxt = span.get_text()
			# Replace commas (,) with punctuations (.):
			tmptxt = tmptxt.replace(',','.')
			# Strip whitespaces:
			tmptxt = tmptxt.strip()
	
			# Get todays price (at the end):
			priceToday = float(tmptxt[-6:])
			# Return this price:
			return priceToday


		# Decide buy value:
		def buyValue():
			global log
			buyPercent = (yesterday - estimated)/yesterday
			buyVal = buyPercent * currentAssetNOK
			return buyVal	

		# Decide sell value:
		def sellValue():
			global log
			sellPercent = (estimated - yesterday)/estimated
			sellVal = sellPercent * currentAssetMWH
			return sellVal

		# Sell all and stop:
		def sellAll():
			global log
			sellVal = currentAssetMWH
			return sellVal

		# Do the trade:
		def trade(estimated, real):
			# Must be global in order to change in this scope:
			global currentAssetMWH
			global currentAssetNOK
			global log

			estimatedError = float(math.fabs(((estimated - real)/real)*100.0))
			# Do the trade:
			print 'Error: (((estimated-system)/system)*100):   ' + repr(estimatedError)
			# if estimatedError <= 3.0:
			log.append("Calculated error:          " + str(estimatedError) + "\n")
			if day != maxDays:
				# Buy if price goes down:
				if estimated < yesterday:
					print 'Buying for:                                 ' + repr(buyValue()) + " NOK" 
					tmpCurrentAssetMWH = currentAssetMWH + buyValue()/real
					print 'Current Asset (MWH):                        ' + repr(tmpCurrentAssetMWH)
					currentAssetMWH = tmpCurrentAssetMWH

					tmpCurrentAssetNOK = currentAssetNOK - buyValue()
					print 'Current Asset (NOK):                        ' + repr(tmpCurrentAssetNOK)
					currentAssetNOK = tmpCurrentAssetNOK
					log.append("Estimated system price:    " + str(estimated) + "\n")
					log.append("Buy volume:                " + str(buyValue()) + "\n")
					log.append("Assets after buy (NOK):    " + str(currentAssetNOK) + "\n")
					log.append("Assets after buy (MWH):    " + str(currentAssetMWH) + "\n")
				

				# Sell if price goes up:
				if estimated > yesterday:
					print 'Selling:                                    ' + repr(sellValue()) + ' MWH'
					tmpCurrentAssetNOK = currentAssetNOK + sellValue() * real
					print 'Current Asset (NOK):                        ' + repr(tmpCurrentAssetNOK)
					currentAssetNOK = tmpCurrentAssetNOK
		
					tmpCurrentAssetMWH = currentAssetMWH - sellValue()
					print "Current Asset (MWH):                        " + repr(tmpCurrentAssetMWH)
					currentAssetMWH = tmpCurrentAssetMWH
					log.append("Estimated system price:    " + str(estimated) + "\n")
					log.append("Sell volume:               " + str(sellValue()) + "\n")
					log.append("Assets after sale (NOK):   " + str(currentAssetNOK) + "\n")
					log.append("Assets after sale (MWH):   " + str(currentAssetMWH) + "\n")
			else:
				# SELL ALL AT END OF DAY 26:
					print 'Sell everything:                            ' + repr(sellAll()) + ' MWH'
					tmpCurrentAssetNOK = currentAssetNOK + sellAll() * real
					print 'Current Asset (NOK):                        ' + repr(tmpCurrentAssetNOK)
					currentAssetNOK = tmpCurrentAssetNOK
					tmpCurrentAssetMWH = currentAssetMWH - sellAll()
					print "Current Asset (MWH):                        " + repr(tmpCurrentAssetMWH)
					currentAssetMWH = tmpCurrentAssetMWH
					log.append("Estimated system price:    " + str(estimated) + "\n")
					log.append("Sell volume:               " + str(sellAll) + "\n")
					log.append("Assets after sale (NOK):   " + str(currentAssetNOK) + "\n")
					log.append("Assets after sale (MWH):   " + str(currentAssetMWH) + "\n")
				
			#else:
				#print "No trade (amount of estimated error is too damn high)"
				#t = currentAssetNOK
				#print "Current Asset (NOK): " + repr(t)
	

		# Open a trained network(all years of data availible):
		fileObject = open('datFile.xml','r')
		net = pickle.load(fileObject)
		fileObject.close()
		# Get todays system price:
		real = webParser()

		# Read datafile:
		f = open('input.txt', 'r')
		inputLines = f.readlines()
		f.close()

		print "Trading (with trained network using 15 nodes, 20 midlayers, 1 output):"
		estimated = float(net.activate([float(inputLines[0])/s, float(inputLines[1])/s, float(inputLines[2])/s, float(inputLines[3])/s, float(inputLines[4])/s, float(inputLines[5])/s, float(inputLines[6])/s, float(inputLines[7])/s, float(inputLines[8])/s, float(inputLines[9])/s, float(inputLines[10])/s, float(inputLines[11])/s, float(inputLines[12])/s, float(inputLines[13])/s, float(inputLines[14])/s])) * 1000.0;
		yesterday = float(inputLines[13])	
		print "Estimated value for day " + repr(day+1) + ":                 " + repr(estimated)
		print "Real system price value for day " + repr(day+1) + ":         " + repr(real)
	
		#Add real value to log-array:
		log.append("Real value of today:       " + str(real) + "\n")

		# Do the trade:
		trade(estimated, real)

		# Fill up an array with new data, and write to input file:
		stack = []
		for i in range(1, len(inputLines)):
			stack.append(str("{0:.2f}".format(float(inputLines[i])))+"\n")
		stack.append(str("{0:.2f}".format(real)))

		### Write new file:
		# Empty input file:
		f = open("input.txt", "w")
		f.write("")
		f.close()
		# append new data:
		with open("input.txt", "a") as f:
			for i in range(0, len(stack)):
				f.write(stack[i])
		f.close()

		# New day:
		day = day + 1
		# Write new init file:
		initLn = [day, currentAssetNOK, currentAssetMWH]
		tmpDay = str(day) + "\n"
		tmpCurAsNOK = str(currentAssetNOK) + "\n"
		tmpCurAsMWH = str(currentAssetMWH)

		# Empty init file:
		f = open("init.txt", "w")
		f.write("")
		f.close()
		# Append new data:
		with open("init.txt", "a") as f:
		    f.write(tmpDay)
		    f.write(tmpCurAsNOK)
		    f.write(tmpCurAsMWH)
		f.close()
		print ""

		log.append("\n")	

		# Create logfile:
		with open("logFile.txt", "a") as f:
			for i in range(0, len(log)):
				f.write(log[i])
		f.close()

	

	time.sleep(10)
	if day > maxDays:
		isRunning = False
		print "Competition is OVER!"
		#Hack to prevent CMD to close:
		while(True):
			time.sleep(1)
